home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / c / icu-1.3.1 / icu-bin / include / gregocal.h < prev    next >
C/C++ Source or Header  |  2000-02-23  |  31KB  |  698 lines

  1. /*
  2. ********************************************************************************
  3. *                                                                              *
  4. * COPYRIGHT:                                                                   *
  5. *   (C) Copyright Taligent, Inc.,  1997                                        *
  6. *   (C) Copyright International Business Machines Corporation,  1997-1999      *
  7. *   Copyright (C) 1999 Alan Liu and others. All rights reserved.               *
  8. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  9. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  10. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  11. *                                                                              *
  12. ********************************************************************************
  13. *
  14. * File GREGOCAL.H
  15. *
  16. * Modification History:
  17. *
  18. *   Date        Name        Description
  19. *   04/22/97    aliu        Overhauled header.
  20. *    07/28/98    stephen        Sync with JDK 1.2
  21. *    09/04/98    stephen        Re-sync with JDK 8/31 putback
  22. *    09/14/98    stephen        Changed type of kOneDay, kOneWeek to double.
  23. *                            Fixed bug in roll() 
  24. *   10/15/99    aliu        Fixed j31, incorrect WEEK_OF_YEAR computation.
  25. *                           Added documentation of WEEK_OF_YEAR computation.
  26. *   10/15/99    aliu        Fixed j32, cannot set date to Feb 29 2000 AD.
  27. *                           {JDK bug 4210209 4209272}
  28. ********************************************************************************
  29. */
  30.          
  31. #ifndef GREGOCAL_H
  32. #define GREGOCAL_H
  33.  
  34.  
  35. #include "calendar.h"
  36.  
  37. /**
  38.  * Concrete class which provides the standard calendar used by most of the world.
  39.  * <P>
  40.  * The standard (Gregorian) calendar has 2 eras, BC and AD.
  41.  * <P>
  42.  * This implementation handles a single discontinuity, which corresponds by default to
  43.  * the date the Gregorian calendar was originally instituted (October 15, 1582). Not all
  44.  * countries adopted the Gregorian calendar then, so this cutover date may be changed by
  45.  * the caller.
  46.  * <P>
  47.  * Prior to the institution of the Gregorian Calendar, New Year's Day was March 25. To
  48.  * avoid confusion, this Calendar always uses January 1. A manual adjustment may be made
  49.  * if desired for dates that are prior to the Gregorian changeover and which fall
  50.  * between January 1 and March 24.
  51.  *
  52.  * <p>Values calculated for the <code>WEEK_OF_YEAR</code> field range from 1 to
  53.  * 53.  Week 1 for a year is the first week that contains at least
  54.  * <code>getMinimalDaysInFirstWeek()</code> days from that year.  It thus
  55.  * depends on the values of <code>getMinimalDaysInFirstWeek()</code>,
  56.  * <code>getFirstDayOfWeek()</code>, and the day of the week of January 1.
  57.  * Weeks between week 1 of one year and week 1 of the following year are
  58.  * numbered sequentially from 2 to 52 or 53 (as needed).
  59.  *
  60.  * <p>For example, January 1, 1998 was a Thursday.  If
  61.  * <code>getFirstDayOfWeek()</code> is <code>MONDAY</code> and
  62.  * <code>getMinimalDaysInFirstWeek()</code> is 4 (these are the values
  63.  * reflecting ISO 8601 and many national standards), then week 1 of 1998 starts
  64.  * on December 29, 1997, and ends on January 4, 1998.  If, however,
  65.  * <code>getFirstDayOfWeek()</code> is <code>SUNDAY</code>, then week 1 of 1998
  66.  * starts on January 4, 1998, and ends on January 10, 1998; the first three days
  67.  * of 1998 then are part of week 53 of 1997.
  68.  *
  69.  * <p>Example for using GregorianCalendar:
  70.  * <pre>
  71.  * .    // get the supported ids for GMT-08:00 (Pacific Standard Time)
  72.  * .    int32_t idsCount;
  73.  * .    const UnicodeString** ids = TimeZone::createAvailableIDs(-8 * 60 * 60 * 1000, idsCount);
  74.  * .    // if no ids were returned, something is wrong. get out.
  75.  * .    if (idsCount == 0) {
  76.  * .        return;
  77.  * .    }
  78.  * .
  79.  * .    // begin output
  80.  * .    cout << "Current Time" << endl;
  81.  * .
  82.  * .    // create a Pacific Standard Time time zone
  83.  * .    SimpleTimeZone* pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *(ids[0]));
  84.  * .    
  85.  * .    // set up rules for daylight savings time
  86.  * .    pdt->setStartRule(Calendar::APRIL, 1, Calendar::SUNDAY, 2 * 60 * 60 * 1000);
  87.  * .    pdt->setEndRule(Calendar::OCTOBER, -1, Calendar::SUNDAY, 2 * 60 * 60 * 1000);
  88.  * .    
  89.  * .    // create a GregorianCalendar with the Pacific Daylight time zone
  90.  * .    // and the current date and time
  91.  * .    UErrorCode success = U_ZERO_ERROR;
  92.  * .    Calendar* calendar = new GregorianCalendar( pdt, success );
  93.  * .    
  94.  * .    // print out a bunch of interesting things
  95.  * .    cout << "ERA: " << calendar->get( Calendar::ERA, success ) << endl;
  96.  * .    cout << "YEAR: " << calendar->get( Calendar::YEAR, success ) << endl;
  97.  * .    cout << "MONTH: " << calendar->get( Calendar::MONTH, success ) << endl;
  98.  * .    cout << "WEEK_OF_YEAR: " << calendar->get( Calendar::WEEK_OF_YEAR, success ) << endl;
  99.  * .    cout << "WEEK_OF_MONTH: " << calendar->get( Calendar::WEEK_OF_MONTH, success ) << endl;
  100.  * .    cout << "DATE: " << calendar->get( Calendar::DATE, success ) << endl;
  101.  * .    cout << "DAY_OF_MONTH: " << calendar->get( Calendar::DAY_OF_MONTH, success ) << endl;
  102.  * .    cout << "DAY_OF_YEAR: " << calendar->get( Calendar::DAY_OF_YEAR, success ) << endl;
  103.  * .    cout << "DAY_OF_WEEK: " << calendar->get( Calendar::DAY_OF_WEEK, success ) << endl;
  104.  * .    cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( Calendar::DAY_OF_WEEK_IN_MONTH, success ) << endl;
  105.  * .    cout << "AM_PM: " << calendar->get( Calendar::AM_PM, success ) << endl;
  106.  * .    cout << "HOUR: " << calendar->get( Calendar::HOUR, success ) << endl;
  107.  * .    cout << "HOUR_OF_DAY: " << calendar->get( Calendar::HOUR_OF_DAY, success ) << endl;
  108.  * .    cout << "MINUTE: " << calendar->get( Calendar::MINUTE, success ) << endl;
  109.  * .    cout << "SECOND: " << calendar->get( Calendar::SECOND, success ) << endl;
  110.  * .    cout << "MILLISECOND: " << calendar->get( Calendar::MILLISECOND, success ) << endl;
  111.  * .    cout << "ZONE_OFFSET: " << (calendar->get( Calendar::ZONE_OFFSET, success )/(60*60*1000)) << endl;
  112.  * .    cout << "DST_OFFSET: " << (calendar->get( Calendar::DST_OFFSET, success )/(60*60*1000)) << endl;
  113.  * .
  114.  * .    cout << "Current Time, with hour reset to 3" << endl;
  115.  * .    calendar->clear(Calendar::HOUR_OF_DAY); // so doesn't override
  116.  * .    calendar->set(Calendar::HOUR, 3);
  117.  * .    cout << "ERA: " << calendar->get( Calendar::ERA, success ) << endl;
  118.  * .    cout << "YEAR: " << calendar->get( Calendar::YEAR, success ) << endl;
  119.  * .    cout << "MONTH: " << calendar->get( Calendar::MONTH, success ) << endl;
  120.  * .    cout << "WEEK_OF_YEAR: " << calendar->get( Calendar::WEEK_OF_YEAR, success ) << endl;
  121.  * .    cout << "WEEK_OF_MONTH: " << calendar->get( Calendar::WEEK_OF_MONTH, success ) << endl;
  122.  * .    cout << "DATE: " << calendar->get( Calendar::DATE, success ) << endl;
  123.  * .    cout << "DAY_OF_MONTH: " << calendar->get( Calendar::DAY_OF_MONTH, success ) << endl;
  124.  * .    cout << "DAY_OF_YEAR: " << calendar->get( Calendar::DAY_OF_YEAR, success ) << endl;
  125.  * .    cout << "DAY_OF_WEEK: " << calendar->get( Calendar::DAY_OF_WEEK, success ) << endl;
  126.  * .    cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( Calendar::DAY_OF_WEEK_IN_MONTH, success ) << endl;
  127.  * .    cout << "AM_PM: " << calendar->get( Calendar::AM_PM, success ) << endl;
  128.  * .    cout << "HOUR: " << calendar->get( Calendar::HOUR, success ) << endl;
  129.  * .    cout << "HOUR_OF_DAY: " << calendar->get( Calendar::HOUR_OF_DAY, success ) << endl;
  130.  * .    cout << "MINUTE: " << calendar->get( Calendar::MINUTE, success ) << endl;
  131.  * .    cout << "SECOND: " << calendar->get( Calendar::SECOND, success ) << endl;
  132.  * .    cout << "MILLISECOND: " << calendar->get( Calendar::MILLISECOND, success ) << endl;
  133.  * .    cout << "ZONE_OFFSET: " << (calendar->get( Calendar::ZONE_OFFSET, success )/(60*60*1000)) << endl; // in hours
  134.  * .    cout << "DST_OFFSET: " << (calendar->get( Calendar::DST_OFFSET, success )/(60*60*1000)) << endl; // in hours
  135.  * .
  136.  * .    delete[] ids;
  137.  * .    delete calendar; // also deletes pdt
  138.  * .
  139.  * </pre>
  140.  */
  141. class U_I18N_API GregorianCalendar: public Calendar {
  142. public:
  143.  
  144.     /**
  145.      * Useful constants for GregorianCalendar and TimeZone.
  146.      */
  147.     enum EEras {
  148.         BC,
  149.         AD
  150.     };
  151.  
  152.     /**
  153.      * Constructs a default GregorianCalendar using the current time in the default time
  154.      * zone with the default locale.
  155.      *
  156.      * @param success  Indicates the status of GregorianCalendar object construction.
  157.      *                 Returns U_ZERO_ERROR if constructed successfully.
  158.      */
  159.     GregorianCalendar(UErrorCode& success);
  160.  
  161.     /**
  162.      * Constructs a GregorianCalendar based on the current time in the given time zone
  163.      * with the default locale. Clients are no longer responsible for deleting the given
  164.      * time zone object after it's adopted.
  165.      *
  166.      * @param zoneToAdopt     The given timezone.
  167.      * @param success  Indicates the status of GregorianCalendar object construction.
  168.      *                 Returns U_ZERO_ERROR if constructed successfully.
  169.      */
  170.     GregorianCalendar(TimeZone* zoneToAdopt, UErrorCode& success);
  171.  
  172.     /**
  173.      * Constructs a GregorianCalendar based on the current time in the given time zone
  174.      * with the default locale.
  175.      *
  176.      * @param zone     The given timezone.
  177.      * @param success  Indicates the status of GregorianCalendar object construction.
  178.      *                 Returns U_ZERO_ERROR if constructed successfully.
  179.      */
  180.     GregorianCalendar(const TimeZone& zone, UErrorCode& success);
  181.  
  182.     /**
  183.      * Constructs a GregorianCalendar based on the current time in the default time zone
  184.      * with the given locale.
  185.      *
  186.      * @param aLocale  The given locale.
  187.      * @param success  Indicates the status of GregorianCalendar object construction.
  188.      *                 Returns U_ZERO_ERROR if constructed successfully.
  189.      */
  190.     GregorianCalendar(const Locale& aLocale, UErrorCode& success);
  191.  
  192.     /**
  193.      * Constructs a GregorianCalendar based on the current time in the given time zone
  194.      * with the given locale. Clients are no longer responsible for deleting the given
  195.      * time zone object after it's adopted.
  196.      *
  197.      * @param zoneToAdopt     The given timezone.
  198.      * @param aLocale  The given locale.
  199.      * @param success  Indicates the status of GregorianCalendar object construction.
  200.      *                 Returns U_ZERO_ERROR if constructed successfully.
  201.      */
  202.     GregorianCalendar(TimeZone* zoneToAdopt, const Locale& aLocale, UErrorCode& success);
  203.  
  204.     /**
  205.      * Constructs a GregorianCalendar based on the current time in the given time zone
  206.      * with the given locale.
  207.      *
  208.      * @param zone     The given timezone.
  209.      * @param aLocale  The given locale.
  210.      * @param success  Indicates the status of GregorianCalendar object construction.
  211.      *                 Returns U_ZERO_ERROR if constructed successfully.
  212.      */
  213.     GregorianCalendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success);
  214.  
  215.     /**
  216.      * Constructs a GregorianCalendar with the given AD date set in the default time
  217.      * zone with the default locale.
  218.      *
  219.      * @param year     The value used to set the YEAR time field in the calendar.
  220.      * @param month    The value used to set the MONTH time field in the calendar. Month
  221.      *                 value is 0-based. e.g., 0 for January.
  222.      * @param date     The value used to set the DATE time field in the calendar.
  223.      * @param success  Indicates the status of GregorianCalendar object construction.
  224.      *                 Returns U_ZERO_ERROR if constructed successfully.
  225.      */
  226.     GregorianCalendar(int32_t year, int32_t month, int32_t date, UErrorCode& success);
  227.  
  228.     /**
  229.      * Constructs a GregorianCalendar with the given AD date and time set for the
  230.      * default time zone with the default locale.
  231.      *
  232.      * @param year     The value used to set the YEAR time field in the calendar.
  233.      * @param month    The value used to set the MONTH time field in the calendar. Month
  234.      *                 value is 0-based. e.g., 0 for January.
  235.      * @param date     The value used to set the DATE time field in the calendar.
  236.      * @param hour     The value used to set the HOUR_OF_DAY time field in the calendar.
  237.      * @param minute   The value used to set the MINUTE time field in the calendar.
  238.      * @param success  Indicates the status of GregorianCalendar object construction.
  239.      *                 Returns U_ZERO_ERROR if constructed successfully.
  240.      */
  241.     GregorianCalendar(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, UErrorCode& success);
  242.  
  243.     /**
  244.      * Constructs a GregorianCalendar with the given AD date and time set for the
  245.      * default time zone with the default locale.
  246.      *
  247.      * @param year     The value used to set the YEAR time field in the calendar.
  248.      * @param month    The value used to set the MONTH time field in the calendar. Month
  249.      *                 value is 0-based. e.g., 0 for January.
  250.      * @param date     The value used to set the DATE time field in the calendar.
  251.      * @param hour     The value used to set the HOUR_OF_DAY time field in the calendar.
  252.      * @param minute   The value used to set the MINUTE time field in the calendar.
  253.      * @param second   The value used to set the SECOND time field in the calendar.
  254.      * @param success  Indicates the status of GregorianCalendar object construction.
  255.      *                 Returns U_ZERO_ERROR if constructed successfully.
  256.      */
  257.     GregorianCalendar(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second, UErrorCode& success);
  258.  
  259.     /**
  260.      * Destructor
  261.      */
  262.     virtual ~GregorianCalendar();
  263.  
  264.     /**
  265.      * Copy constructor
  266.      */
  267.     GregorianCalendar(const GregorianCalendar& source);
  268.  
  269.     /**
  270.      * Default assignment operator
  271.      */
  272.     GregorianCalendar& operator=(const GregorianCalendar& right);
  273.  
  274.     /**
  275.      * Create and return a polymorphic copy of this calendar.
  276.      */
  277.     virtual Calendar* clone(void) const;
  278.  
  279.     /**
  280.      * Sets the GregorianCalendar change date. This is the point when the switch from
  281.      * Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
  282.      * 15, 1582. Previous to this time and date will be Julian dates.
  283.      *
  284.      * @param date     The given Gregorian cutover date.
  285.      * @param success  Output param set to success/failure code on exit.
  286.      */
  287.     void setGregorianChange(UDate date, UErrorCode& success);
  288.  
  289.     /**
  290.      * Gets the Gregorian Calendar change date. This is the point when the switch from
  291.      * Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
  292.      * 15, 1582. Previous to this time and date will be Julian dates.
  293.      *
  294.      * @return   The Gregorian cutover time for this calendar.
  295.      */
  296.     UDate getGregorianChange(void) const;
  297.  
  298.     /**
  299.      * Return true if the given year is a leap year. Determination of whether a year is
  300.      * a leap year is actually very complicated. We do something crude and mostly
  301.      * correct here, but for a real determination you need a lot of contextual
  302.      * information. For example, in Sweden, the change from Julian to Gregorian happened
  303.      * in a complex way resulting in missed leap years and double leap years between
  304.      * 1700 and 1753. Another example is that after the start of the Julian calendar in
  305.      * 45 B.C., the leap years did not regularize until 8 A.D. This method ignores these
  306.      * quirks, and pays attention only to the Julian onset date and the Gregorian
  307.      * cutover (which can be changed).
  308.      *
  309.      * @param year  The given year.
  310.      * @return      True if the given year is a leap year; false otherwise.
  311.      */
  312.     bool_t isLeapYear(int32_t year) const;
  313.  
  314.     /**
  315.      * Compares the equality of two GregorianCalendar objects. Objects of different
  316.      * subclasses are considered unequal.  This is a strict equality test; see the
  317.      * documentation for Calendar::operator==().
  318.      *
  319.      * @param that  The GregorianCalendar object to be compared with.
  320.      * @return      True if the given GregorianCalendar is the same as this
  321.      *              GregorianCalendar; false otherwise.
  322.      */
  323.     virtual bool_t operator==(const Calendar& that) const;
  324.  
  325.     /**
  326.      * Calendar override.
  327.      * Return true if another Calendar object is equivalent to this one.  An equivalent
  328.      * Calendar will behave exactly as this one does, but may be set to a different time.
  329.      */
  330.     virtual bool_t equivalentTo(const Calendar& other) const;
  331.  
  332.     /**
  333.      * (Overrides Calendar) UDate Arithmetic function. Adds the specified (signed) amount
  334.      * of time to the given time field, based on the calendar's rules.  For more
  335.      * information, see the documentation for Calendar::add().
  336.      *
  337.      * @param field   The time field.
  338.      * @param amount  The amount of date or time to be added to the field.
  339.      * @param status  Output param set to success/failure code on exit. If any value
  340.      *                previously set in the time field is invalid, this will be set to
  341.      *                an error status.
  342.      */
  343.     virtual void add(EDateFields field, int32_t amount, UErrorCode& status);
  344.  
  345.     /**
  346.      * (Overrides Calendar) Rolls up or down by the given amount in the specified field.
  347.      * For more information, see the documentation for Calendar::roll().
  348.      *
  349.      * @param field   The time field.
  350.      * @param amount  Indicates amount to roll.
  351.      * @param status  Output param set to success/failure code on exit. If any value
  352.      *                previously set in the time field is invalid, this will be set to
  353.      *                an error status.
  354.      */
  355.     virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);
  356.  
  357.     /**
  358.      * (Overrides Calendar) Returns minimum value for the given field. e.g. for
  359.      * Gregorian DAY_OF_MONTH, 1.
  360.      */
  361.     virtual int32_t getMinimum(EDateFields field) const;
  362.  
  363.     /**
  364.      * (Overrides Calendar) Returns maximum value for the given field. e.g. for
  365.      * Gregorian DAY_OF_MONTH, 31.
  366.      */
  367.     virtual int32_t getMaximum(EDateFields field) const;
  368.  
  369.     /**
  370.      * (Overrides Calendar) Returns highest minimum value for the given field if varies.
  371.      * Otherwise same as getMinimum(). For Gregorian, no difference.
  372.      */
  373.     virtual int32_t getGreatestMinimum(EDateFields field) const;
  374.  
  375.     /**
  376.      * (Overrides Calendar) Returns lowest maximum value for the given field if varies.
  377.      * Otherwise same as getMaximum(). For Gregorian DAY_OF_MONTH, 28.
  378.      */
  379.     virtual int32_t getLeastMaximum(EDateFields field) const;
  380.  
  381.     /**
  382.      * Return the minimum value that this field could have, given the current date.
  383.      * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
  384.      */
  385.     int32_t getActualMinimum(EDateFields field) const;
  386.  
  387.     /**
  388.      * Return the maximum value that this field could have, given the current date.
  389.      * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
  390.      * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
  391.      * for some years the actual maximum for MONTH is 12, and for others 13.
  392.      */
  393.     int32_t getActualMaximum(EDateFields field) const;
  394.  
  395.     /**
  396.      * (Overrides Calendar) Return true if the current date for this Calendar is in
  397.      * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
  398.      *
  399.      * @param status Fill-in parameter which receives the status of this operation.
  400.      * @return   True if the current date for this Calendar is in Daylight Savings Time,
  401.      *           false, otherwise.
  402.      */
  403.     virtual bool_t inDaylightTime(UErrorCode& status) const;
  404.  
  405. public:
  406.  
  407.     /**
  408.      * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
  409.      * override. This method is to implement a simple version of RTTI, since not all C++
  410.      * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
  411.      * this method.
  412.      *
  413.      * @return   The class ID for this object. All objects of a given class have the
  414.      *           same class ID. Objects of other classes have different class IDs.
  415.      */
  416.     virtual UClassID getDynamicClassID(void) const { return (UClassID)&fgClassID; }
  417.  
  418.     /**
  419.      * Return the class ID for this class. This is useful only for comparing to a return
  420.      * value from getDynamicClassID(). For example:
  421.      *
  422.      *      Base* polymorphic_pointer = createPolymorphicObject();
  423.      *      if (polymorphic_pointer->getDynamicClassID() ==
  424.      *          Derived::getStaticClassID()) ...
  425.      *
  426.      * @return   The class ID for all objects of this class.
  427.      */
  428.     static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
  429.  
  430. protected:
  431.  
  432.     /**
  433.      * (Overrides Calendar) Converts GMT as milliseconds to time field values.
  434.      */
  435.     virtual void computeFields(UErrorCode& status);
  436.  
  437.     /**
  438.      * (Overrides Calendar) Converts Calendar's time field values to GMT as
  439.      * milliseconds.
  440.      *
  441.      * @param status  Output param set to success/failure code on exit. If any value
  442.      *                previously set in the time field is invalid, this will be set to
  443.      *                an error status.
  444.      */
  445.     virtual void computeTime(UErrorCode& status);
  446.  
  447. private: 
  448.  
  449.     /**
  450.      * Return the year that corresponds to the <code>WEEK_OF_YEAR</code> field.
  451.      * This may be one year before or after the calendar year stored
  452.      * in the <code>YEAR</code> field.  For example, January 1, 1999 is considered
  453.      * Friday of week 53 of 1998 (if minimal days in first week is
  454.      * 2 or less, and the first day of the week is Sunday).  Given
  455.      * these same settings, the ISO year of January 1, 1999 is
  456.      * 1998.
  457.      * <p>
  458.      * Warning: This method will complete all fields.
  459.      * @return the year corresponding to the <code>WEEK_OF_YEAR</code> field, which
  460.      * may be one year before or after the <code>YEAR</code> field.
  461.      * @see #WEEK_OF_YEAR
  462.      */
  463.     int32_t getISOYear(UErrorCode& status);
  464.  
  465.     /**
  466.      * Return the ERA.  We need a special method for this because the
  467.      * default ERA is AD, but a zero (unset) ERA is BC.
  468.      */
  469.     int32_t internalGetEra() const;
  470.  
  471.     // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
  472.     static const UDate EARLIEST_SUPPORTED_MILLIS;
  473.     static const UDate LATEST_SUPPORTED_MILLIS;
  474.  
  475.     int32_t monthLength(int32_t month) const;
  476.     int32_t monthLength(int32_t month, int32_t year) const;
  477.  
  478.     int32_t yearLength(int32_t year) const;
  479.  
  480.     int32_t yearLength(void) const;
  481.  
  482.     /**
  483.      * After adjustments such as add(MONTH), add(YEAR), we don't want the
  484.      * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
  485.      * 3, we want it to go to Feb 28.  Adjustments which might run into this
  486.      * problem call this method to retain the proper month.
  487.      */
  488.     void pinDayOfMonth(void);
  489.  
  490.     /**
  491.      * Return the day number with respect to the epoch.  January 1, 1970 (Gregorian)
  492.      * is day zero.
  493.      */
  494.     UDate getEpochDay(UErrorCode& status);
  495.  
  496.     /**
  497.      * Compute the Julian day number under either the Gregorian or the
  498.      * Julian calendar, using the given year and the remaining fields.
  499.      * @param isGregorian if true, use the Gregorian calendar
  500.      * @param year the adjusted year number, with 0 indicating the
  501.      * year 1 BC, -1 indicating 2 BC, etc.
  502.      * @return the Julian day number
  503.      */
  504.     double computeJulianDay(bool_t isGregorian, int32_t year);
  505.  
  506.     /**
  507.      * Compute the date-based fields given the milliseconds since the epoch start. Do
  508.      * not compute the time-based fields (HOUR, MINUTE, etc.).
  509.      *
  510.      * @param theTime the time in wall millis (either Standard or DST),
  511.      * whichever is in effect
  512.      * @param quick if true, only compute the ERA, YEAR, MONTH, DATE,
  513.      * DAY_OF_WEEK, and DAY_OF_YEAR.
  514.      */
  515.     void timeToFields(UDate theTime, bool_t quick, UErrorCode& status);
  516.  
  517.  
  518.     /**
  519.      * Return the week number of a day, within a period. This may be the week number in
  520.      * a year, or the week number in a month. Usually this will be a value >= 1, but if
  521.      * some initial days of the period are excluded from week 1, because
  522.      * minimalDaysInFirstWeek is > 1, then the week number will be zero for those
  523.      * initial days. Requires the day of week for the given date in order to determine
  524.      * the day of week of the first day of the period.
  525.      *
  526.      * @param date  Day-of-year or day-of-month. Should be 1 for first day of period.
  527.      * @param day   Day-of-week for given dayOfPeriod. 1-based with 1=Sunday.
  528.      * @return      Week number, one-based, or zero if the day falls in part of the
  529.      *              month before the first week, when there are days before the first
  530.      *              week because the minimum days in the first week is more than one.
  531.      */
  532.     int32_t weekNumber(int32_t date, int32_t day);
  533.  
  534.     /**
  535.      * Validates the values of the set time fields.  True if they're all valid.
  536.      */
  537.     bool_t validateFields(void) const;
  538.  
  539.     /**
  540.      * Validates the value of the given time field.  True if it's valid.
  541.      */
  542.     bool_t boundsCheck(int32_t value, EDateFields field) const;
  543.  
  544.     /**
  545.      * Return the pseudo-time-stamp for two fields, given their
  546.      * individual pseudo-time-stamps.  If either of the fields
  547.      * is unset, then the aggregate is unset.  Otherwise, the
  548.      * aggregate is the later of the two stamps.
  549.      */
  550.     EStampValues aggregateStamp(EStampValues stamp_a, EStampValues stamp_b);
  551.  
  552.     /**
  553.      * The point at which the Gregorian calendar rules are used, measured in
  554.      * milliseconds from the standard epoch.  Default is October 15, 1582
  555.      * (Gregorian) 00:00:00 UTC, that is, October 4, 1582 (Julian) is followed
  556.      * by October 15, 1582 (Gregorian).  This corresponds to Julian day number
  557.      * 2299161.
  558.      */
  559.     // This is measured from the standard epoch, not in Julian Days.
  560.     UDate                fGregorianCutover;
  561.  
  562.     /**
  563.      * Midnight, local time (using this Calendar's TimeZone) at or before the
  564.      * gregorianCutover. This is a pure date value with no time of day or
  565.      * timezone component.
  566.      */
  567.     UDate                 fNormalizedGregorianCutover;// = gregorianCutover;
  568.  
  569.     /**
  570.      * The year of the gregorianCutover, with 0 representing
  571.      * 1 BC, -1 representing 2 BC, etc.
  572.      */
  573.     int32_t fGregorianCutoverYear;// = 1582;
  574.  
  575.     static char fgClassID;
  576.  
  577.     /**
  578.      * Converts time as milliseconds to Julian date. The Julian date used here is not a
  579.      * true Julian date, since it is measured from midnight, not noon.
  580.      *
  581.      * @param millis  The given milliseconds.
  582.      * @return        The Julian date number.
  583.      */
  584.     static double millisToJulianDay(UDate millis);
  585.  
  586.     /**
  587.      * Converts Julian date to time as milliseconds. The Julian date used here is not a
  588.      * true Julian date, since it is measured from midnight, not noon.
  589.      *
  590.      * @param julian  The given Julian date number.
  591.      * @return        Time as milliseconds.
  592.      */
  593.     static UDate julianDayToMillis(double julian);
  594.  
  595.     /**
  596.      * Convert a quasi Julian date to the day of the week. The Julian date used here is
  597.      * not a true Julian date, since it is measured from midnight, not noon. Return
  598.      * value is one-based.
  599.      *
  600.      * @return   Day number from 1..7 (SUN..SAT).
  601.      */
  602.     static uint8_t julianDayToDayOfWeek(double julian);
  603.  
  604.     /**
  605.      * Divide two long integers, returning the floor of the quotient.
  606.      * <p>
  607.      * Unlike the built-in division, this is mathematically well-behaved.
  608.      * E.g., <code>-1/4</code> => 0
  609.      * but <code>floorDivide(-1,4)</code> => -1.
  610.      * @param numerator the numerator
  611.      * @param denominator a divisor which must be > 0
  612.      * @return the floor of the quotient.
  613.      */
  614.     static double floorDivide(double numerator, double denominator);
  615.  
  616.     /**
  617.      * Divide two integers, returning the floor of the quotient.
  618.      * <p>
  619.      * Unlike the built-in division, this is mathematically well-behaved.
  620.      * E.g., <code>-1/4</code> => 0
  621.      * but <code>floorDivide(-1,4)</code> => -1.
  622.      * @param numerator the numerator
  623.      * @param denominator a divisor which must be > 0
  624.      * @return the floor of the quotient.
  625.      */
  626.     static int32_t floorDivide(int32_t numerator, int32_t denominator);
  627.  
  628.     /**
  629.      * Divide two integers, returning the floor of the quotient, and
  630.      * the modulus remainder.
  631.      * <p>
  632.      * Unlike the built-in division, this is mathematically well-behaved.
  633.      * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
  634.      * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
  635.      * @param numerator the numerator
  636.      * @param denominator a divisor which must be > 0
  637.      * @param remainder an array of at least one element in which the value
  638.      * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
  639.      * % denominator</code>, this will always be non-negative.
  640.      * @return the floor of the quotient.
  641.      */
  642.     static int32_t floorDivide(int32_t numerator, int32_t denominator, int32_t remainder[]);
  643.  
  644.     /**
  645.      * Divide two integers, returning the floor of the quotient, and
  646.      * the modulus remainder.
  647.      * <p>
  648.      * Unlike the built-in division, this is mathematically well-behaved.
  649.      * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
  650.      * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
  651.      * @param numerator the numerator
  652.      * @param denominator a divisor which must be > 0
  653.      * @param remainder an array of at least one element in which the value
  654.      * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
  655.      * % denominator</code>, this will always be non-negative.
  656.      * @return the floor of the quotient.
  657.      */
  658.     static int32_t floorDivide(double numerator, int32_t denominator, int32_t remainder[]);
  659.  
  660.  
  661.     static const UDate       kPapalCutover;             // Cutover decreed by Pope Gregory
  662.  
  663.     static const int32_t     kJan1_1JulianDay;        // January 1, year 1 (Gregorian)
  664.     static const int32_t     kEpochStartAsJulianDay; // January 1, 1970 (Gregorian)
  665.     static const int32_t     kEpochYear;
  666.  
  667.     static const int32_t     kNumDays [];
  668.     static const int32_t     kLeapNumDays [];
  669.     static const int32_t     kMonthLength [];
  670.     static const int32_t     kLeapMonthLength [];
  671.  
  672.     static const int32_t     kMinValues [];
  673.     static const int32_t     kLeastMaxValues [];
  674.     static const int32_t     kMaxValues [];
  675.  
  676.     // Useful millisecond constants
  677.     static const int32_t    kOneSecond;
  678.     static const int32_t    kOneMinute;
  679.     static const int32_t    kOneHour;
  680.     static const double        kOneDay;
  681.     static const double        kOneWeek;
  682. };
  683.  
  684.  
  685. inline uint8_t GregorianCalendar::julianDayToDayOfWeek(double julian)
  686. {
  687.   // If julian is negative, then julian%7 will be negative, so we adjust
  688.   // accordingly.  We add 1 because Julian day 0 is Monday.
  689.   int8_t dayOfWeek = (int8_t) icu_fmod(julian + 1, 7);
  690.   
  691.   uint8_t result = dayOfWeek + ((dayOfWeek < 0) ? (7 + SUNDAY) : SUNDAY);
  692.   return result;
  693. }
  694.  
  695. #endif // _GREGOCAL
  696. //eof
  697.         
  698.